The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
.gitignore 01
Changes 010
MANIFEST 13
META.yml 11
Makefile.PL 04
README 11
calc.h 11
callback_stubs.inc 11
exprpstr.inc 01
lib/HTML/Template/PerlInterface.pod 55
lib/HTML/Template/Pro/CommonTest.pm 1610
lib/HTML/Template/Pro.pm 22
lib/HTML/Template/SYNTAX.pod 22
loadfile.inc 55
pconst.h 01
perl-HTML-Template-Pro.spec 17
procore.c 512
procore.h 15
t/HTML/Template/Pro/CommonTest.pm 0172
t/HTML-Template-Expr.t 12
t/HTML-Template-Pro.t 01
t/error_output.t 019
t/htp_version.t 014
tags.inc 77
templates-Pro/test_esc4.out 02
templates-Pro/test_esc4.tmpl 02
templates-Pro/test_expr5.out 07
templates-Pro/test_expr5.tmpl 07
tmplpro_version.c 04
29 files changed (This is a version diff) 195299
@@ -14,6 +14,7 @@ pm_to_blib
 Makefile.old
 semantic.cache
 templates-Pro/json
+templates-Pro/json-cs
 getoptint.re2c.inc
 resetopt0.inc
 resetoptnot0.inc
@@ -293,3 +293,13 @@ Revision history for Perl extension HTML::Template::Pro.
 09502 Fri Jun 18 18:02:28 EEST 2010
 	- bugfix release: segfault for string operetions
 	with undefined variables. Thanks to Mike Shogin.
+
+09503 Sat Aug 28 18:00:49 EEST 2010
+	- log file is not truncated now in tmplpro_set_log_file.
+	- freed memory access error fixed.
+	- perl: CommonTest.pm hidden from installation
+	- tests: added generic json-packed test data 
+
+09504 Tue Sep 28 17:16:55 EEST 2010
+	- bugfix in string comparision
+	- spelling fix by gregor herrmann <gregoa@debian.org>
@@ -27,7 +27,6 @@ exprtype.h
 exprval.h
 lib/HTML/Template/PerlInterface.pod
 lib/HTML/Template/Pro.pm
-lib/HTML/Template/Pro/CommonTest.pm
 lib/HTML/Template/Pro/WrapAssociate.pm
 lib/HTML/Template/SYNTAX.pod
 loadfile.h
@@ -65,9 +64,12 @@ t/03complex.t
 t/04register.t
 t/05path_like_variable_scope.t
 t/06loop_var.t
+t/error_output.t
 t/HTML-Template-Expr.t
 t/HTML-Template-Pro.t
 t/HTML-Template.t
+t/HTML/Template/Pro/CommonTest.pm
+t/htp_version.t
 t/magic.t
 t/pod.t
 t/realloc.t
@@ -1,6 +1,6 @@
 --- #YAML:1.0
 name:               HTML-Template-Pro
-version:            0.9502
+version:            0.9504
 abstract:           Perl/XS module to use HTML Templates from CGI scripts
 author:
     - I. Yu. Vlasenko <viy@altlinux.org>
@@ -9,6 +9,8 @@ $Verbose = 1;
 
 my ($INC, $DEFINE, $LIBS, $O_FILES, $STATIC_BUILD);
 
+our $VERSION='';
+eval `grep 'VERSION *=' lib/HTML/Template/Pro.pm`;
 
 if (grep {/^DYNAMIC=1/} @ARGV) {
     $STATIC_BUILD=0;
@@ -31,6 +33,8 @@ my %DEF=(
     MMAP  => 1,
     IMITATE=>0,
 );
+$DEF{PACKAGE_VERSION}=$VERSION if $VERSION;
+
 
 &configure() if $STATIC_BUILD;
 
@@ -1,4 +1,4 @@
-HTML-Template-Pro version 0.9502
+HTML-Template-Pro version 0.9504
 ==============================
 
 DESCRIPTION
@@ -14,7 +14,7 @@ typedef struct exprval (*func_t_ee) (struct expr_parser* exprobj, struct exprval
 struct symrec_const
 {
   char *name;  /* name of symbol */
-  int len;     /* symbol length */;
+  int len;     /* symbol length */
   int type;    /* type of symbol: either VAR or FNCT */
   double var;      /* value of a VAR */
   void* fnctptr;  /* value of a FNCT */
@@ -37,7 +37,7 @@ static void BACKCALL stub_write_chars_to_pbuffer (ABSTRACT_WRITER* state,const c
 }
 
 static ABSTRACT_USERFUNC* BACKCALL stub_is_expr_userfnc_func (ABSTRACT_FUNCMAP* af, PSTRING name) {
-  tmpl_log(TMPL_LOG_ERROR,"is_expr_userfnc_func stub: EXPR is not initialized properly. user func dispatcher was not supplied.");
+  tmpl_log(TMPL_LOG_DEBUG,"is_expr_userfnc_func stub: EXPR is not initialized properly. user func dispatcher was not supplied.\n");
   return NULL;
 }
 
@@ -86,6 +86,7 @@ pstring_eq(PSTRING a, PSTRING b) {
   const char* in_a=a.begin;
   const char* in_b=b.begin;
   if (in_a==NULL || in_b==NULL) return in_a == in_b;
+  if (in_a==a.endnext) return in_b==b.endnext;
   while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
   if (in_a==a.endnext && in_b==b.endnext && *(--in_a) == *(--in_b)) return 1; else return 0;
 }
@@ -386,7 +386,7 @@ If case_sensitive is set to 0, the perl wrapper is forced to lowercase
 keys in every hash it will find in "param" tree, which is sometimes 
 an expensive operation. To avoid this, set case_sensitive => 1.
 
-If case conversion is nessessary, there is an alternative lightweight 
+If case conversion is necessary, there is an alternative lightweight
 option tmpl_var_case, which is HTML::Template::Pro specific.
 
 Note that case_sensitive is wrapper-only option: it is not implemented 
@@ -540,7 +540,7 @@ HTML::Template reads your template file but before it starts parsing
 template tags.
 
 In the most simple usage, you simply assign a code reference to the
-filter parameter.  This subroutine will recieve a single argument - a
+filter parameter.  This subroutine will receive a single argument - a
 reference to a string containing the template file text.  Here is an
 example that accepts templates with tags that look like "!!!ZAP_VAR
 FOO!!!" and transforms them into HTML::Template tags:
@@ -630,7 +630,7 @@ C<param()> can be called in a number of ways
       $self->param(PARAM => 'value');
 
       # with a subroutine reference that gets called to get the value
-      # of the scalar.  The sub will recieve the template object as a
+      # of the scalar.  The sub will receive the template object as a
       # parameter.
       $self->param(PARAM => sub { return 'value' });   
 
@@ -902,7 +902,7 @@ or
   HTML::Template::Expr->register_function(func_name => \&func_handler);
 
 You provide a subroutine reference that will be called during output.
-It will recieve as arguments the parameters specified in the template.
+It will receive as arguments the parameters specified in the template.
 For example, here's a function that checks if a directory exists:
 
   sub directory_exists {
@@ -982,7 +982,7 @@ HTML::Template::Pro does not forces the HTML::Template global_vars
 option to be set, whereas currently HTML::Template::Expr does.
 Anyway, this also will hopefully go away in a future version of 
 HTML::Template::Expr, so if you need global_vars in your templates 
-then you should set it explicitely.
+then you should set it explicitly.
 
 
 
@@ -1,161 +0,0 @@
-package HTML::Template::Pro::CommonTest;
-
-use strict;
-use warnings;
-use Carp;
-
-use Test;
-use File::Spec;
-use File::Path;
-use HTML::Template::Pro qw/:const/;
-#use Data::Dumper;
-use JSON;
-require Exporter;
-use vars qw/@ISA @EXPORT/;
-@ISA=qw/Exporter/;
-@EXPORT =qw/test_tmpl test_tmpl_std test_tmpl_expr dryrun/;
-
-use vars qw/$DumpDir/;
-$DumpDir='json';
-
-#$Data::Dumper::Terse=1;
-#$Data::Dumper::Indent=1;
-#$Data::Dumper::Useqq=1;
-#$Data::Dumper::Pair = ' : ';
-
-#########################
-
-my $DEBUG=$ENV{HTP_DEBUG};
-$DEBUG||=0;
-
-sub test_tmpl {
-    my $file=shift;
-    my $optref=shift;
-    my @param=@_;
-    my $tmpl;
-    print "\n--------------- Test: $file ---------------------\n";
-    chdir 'templates-Pro';
-    $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl',debug=>$DEBUG, @$optref);
-    $tmpl->param(@param);
-    &dryrun($tmpl,$file);
-    $ENV{HTP_DUMP} && &dump_test ($file,{@$optref},{@param});
-    chdir '..';
-}
-
-sub test_tmpl_expr {
-    my $file=shift;
-    my $tmpl;
-    print "\n--------------- Test: $file ---------------------\n";
-    chdir 'templates-Pro';
-    $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl', loop_context_vars=>1, case_sensitive=>1,tmpl_var_case=>ASK_NAME_UPPERCASE|ASK_NAME_AS_IS,debug=>$DEBUG, functions=>{'hello' => sub { return "hi, $_[0]!" }});
-    $tmpl->param(@_);
-    # per-object extension
-    $tmpl->register_function('per_object_call' => sub { return shift()."-arg"});
-    $tmpl->register_function('perobjectcall2' => sub { return shift()."-arg"});
-    &dryrun($tmpl,$file);
-    chdir '..';
-}
-
-my $case_ext = [
-    loop_context_vars=>1,
-    case_sensitive=>0,
-    ];
-my $case_int = [
-    loop_context_vars=>1,
-    case_sensitive=>1,
-    tmpl_var_case=>ASK_NAME_UPPERCASE,
-    ];
-
-sub test_tmpl_std {
-    my ($file,@args)=@_;
-    &test_tmpl($file, $case_ext, @args);
-    &test_tmpl($file, $case_int, @args);
-}
-
-sub dryrun {
-    my $tmpl=shift;
-    my $file=shift;
-    open (OUTFILE, ">$file.raw") || die "can't open $file.raw: $!";
-    binmode (OUTFILE);
-    $tmpl->output(print_to => *OUTFILE);
-    close (OUTFILE) || die "can't close $file.raw: $!";
-    my $fileout = &catfile("$file.out");
-    my $files_equal=&catfile("$file.raw") eq $fileout;
-    if ($files_equal) {
-	ok($files_equal) && unlink "$file.raw";
-    } else {
-	if (-x '/usr/bin/diff') {
-	    print STDERR `diff -u $file.out $file.raw`;
-	} else {
-	    print STDERR "# >>> ---$file.raw---\nTODO: diff here\n>>> ---end $file.raw---\n";
-	}
-    }
-    my $output=$tmpl->output();
-    ok (defined $output and $output eq $fileout);
-}
-
-sub catfile {
-    my $file=shift;
-    open (INFILE, $file) || die "can't open $file: $!";
-    binmode (INFILE);
-    local $/;
-    my $catfile=<INFILE>;
-    close (INFILE) || die "can't close $file: $!";
-    return $catfile;
-}
-
-my %filename_counter;
-$0=~/([\w_-]+)(?:\.t)$/;
-my $dump_prefix = $1 ? "$1-" : '';
-sub _dump_file_name {
-    my ($file) = @_;
-    my $plain=$file;
-    $plain=~s![\\/:]!_!g;
-    return File::Spec->catfile($DumpDir, 
-      $dump_prefix.$plain.'-'.sprintf("%.2d",++$filename_counter{$file}).'.json');
-}
-
-sub dump_test {
-    my ($file,$optref,$paramref) = @_;
-    mkpath ($DumpDir);
-    my $dump_file = _dump_file_name($file);
-    open FH, '>', $dump_file or die "can't open ($!) ".$dump_file;
-    my $tojson = {
-	'file' => $file,
-	'options' => $optref,
-	'params' => $paramref,
-    };
-    print FH to_json($tojson, {utf8 => 1, pretty => 1});
-    close (FH) or die "can't close ($!) ".$dump_file;
-}
-
-### Local Variables: 
-### mode: perl
-### End: 
-
-
-1;
-
-__END__
-
-#head1 NAME
-
-HTML::Template::Pro::CommonTest - internal common test library
-
-#head1 DESCRIPTION
-
-internal common test library
-
-#head1 AUTHOR
-
-I. Vlasenko, E<lt>viy@altlinux.orgE<gt>
-
-#head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2009 by I. Yu. Vlasenko.
-
-This library is free software; you can redistribute it and/or modify it under 
-either the LGPL2+ or under the same terms as Perl itself, either Perl version 5.8.4 
-or, at your option, any later version of Perl 5 you may have available.
-
-#cut
@@ -12,7 +12,7 @@ require Exporter;
 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
 @ISA = qw(DynaLoader Exporter);
 
-$VERSION = '0.9502';
+$VERSION = '0.9504';
 
 @EXPORT_OK = qw/ASK_NAME_DEFAULT ASK_NAME_AS_IS ASK_NAME_LOWERCASE ASK_NAME_UPPERCASE ASK_NAME_MASK/;
 %EXPORT_TAGS = (const => [qw/ASK_NAME_DEFAULT ASK_NAME_AS_IS ASK_NAME_LOWERCASE ASK_NAME_UPPERCASE ASK_NAME_MASK/]);
@@ -462,7 +462,7 @@ HTML::Template::Pro is a fast lightweight C/Perl+XS reimplementation
 of HTML::Template (as of 2.9) and HTML::Template::Expr (as of 0.0.7). 
 It is not intended to be a complete replacement, 
 but to be a fast implementation of HTML::Template if you don't need 
-quering, the extended facility of HTML::Template.
+querying, the extended facility of HTML::Template.
 Designed for heavy upload, resource limitations, abcence of mod_perl.
 
 HTML::Template::Pro has complete support of filters and HTML::Template::Expr's 
@@ -282,7 +282,7 @@ available.  As a final attempt, the filename is passed to open()
 directly.  See below for more information on HTML_TEMPLATE_ROOT and
 the "path" option to new().
 
-As a protection against infinitly recursive includes, an arbitary
+As a protection against infinitly recursive includes, an arbitrary
 limit of 10 levels deep is imposed.  You can alter this limit with the
 "max_includes" option.  See the entry for the "max_includes" option
 below for more details.
@@ -607,7 +607,7 @@ regexp support is added to HTML::Template::Expr and
 HTML::Template::Pro by Stanislav Yadykin <tosick at altlinux.ru>.
 Currently it is not included in official distribution of HTML::Template::Expr.
 
-Standart regexp syntax:
+Standard regexp syntax:
 
 =over 4
 
@@ -139,8 +139,8 @@ mmap_load_file (const char* filepath) {
   stream = fopen(filepath, "r");
   if (stream == NULL) return memarea; /* {NULL,NULL} */
   /* mmap size_in_bytes+1 to avoid crash with empty file */
-  memarea.begin=(char*) malloc(memsize+1);
-  writepoint=memarea.begin;
+  memarea.begin=(const char*) malloc(memsize+1);
+  writepoint=(char*)memarea.begin;
 
   while (1) {
     realsize=fread(writepoint, 1, chunksize, stream);
@@ -149,8 +149,8 @@ mmap_load_file (const char* filepath) {
       writepoint+=chunksize;
       if (size_in_bytes+chunksize>memsize) {
 	memsize*=2;
-	memarea.begin=(char*) realloc(memarea.begin, memsize+1);
-	writepoint=memarea.begin+size_in_bytes;
+	memarea.begin=(char*) realloc((char*)memarea.begin, memsize+1);
+	writepoint=((char*)memarea.begin)+size_in_bytes;
       }
     } else {
       fclose(stream);
@@ -164,7 +164,7 @@ static
 int 
 mmap_unload_file (PSTRING memarea) {
   /* destroying */
-  free(memarea.begin);
+  free((char*)memarea.begin);
   return 0;
 }
 
@@ -7,6 +7,7 @@
 #define ERR_PRO_FILE_NOT_FOUND 2
 #define ERR_PRO_CANT_OPEN_FILE 3
 #define ERR_PRO_TEMPLATE_SYNTAX_ERROR 4
+#define ERR_PRO_NOT_ENOUGH_MEMORY 5
 
 #endif /* pconst.h */
 
@@ -6,7 +6,7 @@
 %define module HTML-Template-Pro
 
 Name: perl-%module
-Version: 0.9502
+Version: 0.9504
 Release: alt1
 
 Packager: Igor Yu. Vlasenko <viy@altlinux.org>
@@ -54,6 +54,12 @@ in the Perl script.
 %perl_vendor_man3dir/*
 
 %changelog
+* Tue Sep 28 2010 Igor Vlasenko <viy@altlinux.ru> 0.9504-alt1
+- new version; see Changes
+
+* Sat Aug 28 2010 Igor Vlasenko <viy@altlinux.ru> 0.9503-alt1
+- new version; see Changes
+
 * Thu Jun 17 2010 Igor Vlasenko <viy@altlinux.ru> 0.9502-alt1
 - new version; see Changes
 
@@ -429,6 +429,7 @@ tmplpro_exec_tmpl_filename (struct tmplpro_param *param, const char* filename)
   int mmapstatus;
   PSTRING memarea;
   int retval = 0;
+  const char* saved_masterpath;
   /* 
    * param->masterpath is path to upper level template 
    * (or NULL in toplevel) which called <include filename>.
@@ -439,7 +440,8 @@ tmplpro_exec_tmpl_filename (struct tmplpro_param *param, const char* filename)
   if (NULL==filepath) return ERR_PRO_FILE_NOT_FOUND;
   /* filepath should be alive for every nested template */
   filepath = strdup(filepath);
-
+  if (NULL==filepath) return ERR_PRO_NOT_ENOUGH_MEMORY;
+  saved_masterpath=param->masterpath; /* saving current file name */
   param->masterpath=filepath;
   if (param->filters) memarea=(param->LoadFileFuncPtr)(param->ext_filter_state,filepath);
   else memarea=mmap_load_file(filepath);
@@ -460,6 +462,7 @@ tmplpro_exec_tmpl_filename (struct tmplpro_param *param, const char* filename)
   else mmapstatus=mmap_unload_file(memarea);
  cleanup_filepath:
   if (filepath!=NULL) free((void*) filepath);
+  param->masterpath=saved_masterpath;
   return retval;
 }
 
@@ -468,12 +471,16 @@ int
 tmplpro_exec_tmpl_scalarref (struct tmplpro_param *param, PSTRING memarea)
 {
   struct tmplpro_state state;
+  const char* saved_masterpath=param->masterpath; /* saving current file name */
   param->masterpath=NULL; /* no upper file */
   state.top = memarea.begin;
   state.next_to_end=memarea.endnext;
-  if (memarea.begin == memarea.endnext) return 0;
-  init_state(&state,param);
-  process_state(&state);
+  if (memarea.begin != memarea.endnext) {
+    init_state(&state,param);
+    process_state(&state);
+  }
+  /* exit cleanup code */
+  param->masterpath=saved_masterpath;
   return 0;
 }
 
@@ -694,7 +701,7 @@ tmplpro_set_log_file(struct tmplpro_param* param, const char* logfilename)
     tmpl_log_set_callback(tmpl_log_default_callback);
     return 0;
   }
-  file_p = fopen(logfilename, "w");
+  file_p = fopen(logfilename, "a");
   if (!file_p) {
     tmpl_log(TMPL_LOG_ERROR,"tmplpro_set_log_file: can't create log file [%s]\n",logfilename);
     return ERR_PRO_FILE_NOT_FOUND;
@@ -12,7 +12,11 @@ static const char* const errlist[] = {
   "invalid argument",
   "file not found",
   "can't open file",
-  "syntax error in template"
+  "syntax error in template",
+  "not enough memory (allocation error)",
+  "",
+  "",
+  ""
 };
 
 /* 
@@ -0,0 +1,172 @@
+package HTML::Template::Pro::CommonTest;
+
+use strict;
+use warnings;
+use Carp;
+
+use Test;
+use File::Spec;
+use File::Path;
+use HTML::Template::Pro qw/:const/;
+#use Data::Dumper;
+use JSON;
+require Exporter;
+use vars qw/@ISA @EXPORT/;
+@ISA=qw/Exporter/;
+@EXPORT =qw/test_tmpl test_tmpl_std test_tmpl_expr dryrun/;
+
+use vars qw/$DumpDir $DumpDir_no_cs/;
+$DumpDir='json-cs';
+$DumpDir_no_cs='json';
+
+#$Data::Dumper::Terse=1;
+#$Data::Dumper::Indent=1;
+#$Data::Dumper::Useqq=1;
+#$Data::Dumper::Pair = ' : ';
+
+#########################
+
+my $DEBUG=$ENV{HTP_DEBUG};
+$DEBUG||=0;
+
+sub test_tmpl {
+    my $file=shift;
+    my $optref=shift;
+    my @param=@_;
+    my $tmpl;
+    print "\n--------------- Test: $file ---------------------\n";
+    chdir 'templates-Pro';
+    $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl',debug=>$DEBUG, @$optref);
+    $tmpl->param(@param);
+    &dryrun($tmpl,$file);
+    $ENV{HTP_DUMP} && &dump_test ($file,{@$optref},{@param});
+    chdir '..';
+}
+
+sub test_tmpl_expr {
+    my $file=shift;
+    my $tmpl;
+    print "\n--------------- Test: $file ---------------------\n";
+    chdir 'templates-Pro';
+    $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl', loop_context_vars=>1, case_sensitive=>1,tmpl_var_case=>ASK_NAME_UPPERCASE|ASK_NAME_AS_IS,debug=>$DEBUG, functions=>{'hello' => sub { return "hi, $_[0]!" }});
+    $tmpl->param(@_);
+    # per-object extension
+    $tmpl->register_function('per_object_call' => sub { return shift()."-arg"});
+    $tmpl->register_function('perobjectcall2' => sub { return shift()."-arg"});
+    &dryrun($tmpl,$file);
+    chdir '..';
+}
+
+my $case_ext = [
+    loop_context_vars=>1,
+    case_sensitive=>0,
+    ];
+my $case_int = [
+    loop_context_vars=>1,
+    case_sensitive=>1,
+    tmpl_var_case=>ASK_NAME_UPPERCASE,
+    ];
+
+sub test_tmpl_std {
+    my ($file,@args)=@_;
+    &test_tmpl($file, $case_ext, @args);
+    &test_tmpl($file, $case_int, @args);
+}
+
+sub dryrun {
+    my $tmpl=shift;
+    my $file=shift;
+    open (OUTFILE, ">$file.raw") || die "can't open $file.raw: $!";
+    binmode (OUTFILE);
+    $tmpl->output(print_to => *OUTFILE);
+    close (OUTFILE) || die "can't close $file.raw: $!";
+    my $fileout = &catfile("$file.out");
+    my $files_equal=&catfile("$file.raw") eq $fileout;
+    if ($files_equal) {
+	ok($files_equal) && unlink "$file.raw";
+    } else {
+	if (-x '/usr/bin/diff') {
+	    print STDERR `diff -u $file.out $file.raw`;
+	} else {
+	    print STDERR "# >>> ---$file.raw---\nTODO: diff here\n>>> ---end $file.raw---\n";
+	}
+    }
+    my $output=$tmpl->output();
+    ok (defined $output and $output eq $fileout);
+}
+
+sub catfile {
+    my $file=shift;
+    open (INFILE, $file) || die "can't open $file: $!";
+    binmode (INFILE);
+    local $/;
+    my $catfile=<INFILE>;
+    close (INFILE) || die "can't close $file: $!";
+    return $catfile;
+}
+
+my %filename_counter;
+$0=~/([\w_-]+)(?:\.t)$/;
+my $dump_prefix = $1 ? "$1-" : '';
+sub _dump_file_name {
+    my ($DumpDir,$file) = @_;
+    my $plain=$file;
+    $plain=~s![\\/:]!_!g;
+    return File::Spec->catfile($DumpDir, 
+      $dump_prefix.$plain.'-'.sprintf("%.2d",++$filename_counter{$file}).'.json');
+}
+
+sub dump_test {
+    my ($file,$optref,$paramref) = @_;
+    mkpath ([$DumpDir,$DumpDir_no_cs]);
+    my $tojson = {
+	'file' => $file,
+	'options' => $optref,
+	'params' => $paramref,
+    };
+    &__dump_json(&_dump_file_name($DumpDir,$file), $tojson);
+    my $case_sensitive=$optref->{'case_sensitive'};
+    if (defined $case_sensitive) {
+	delete $optref->{'case_sensitive'};
+	$optref->{'tmpl_var_case'}=ASK_NAME_UPPERCASE unless $case_sensitive;
+    }
+    &__dump_json(&_dump_file_name($DumpDir_no_cs,$file), $tojson);
+}
+
+sub __dump_json {
+    my ($dump_file, $tojson) = @_;
+    open FH, '>', $dump_file or die "can't open ($!) ".$dump_file;
+    print FH to_json($tojson, {utf8 => 1, pretty => 1});
+    close (FH) or die "can't close ($!) ".$dump_file;
+}
+
+### Local Variables: 
+### mode: perl
+### End: 
+
+
+1;
+
+__END__
+
+#head1 NAME
+
+HTML::Template::Pro::CommonTest - internal common test library
+
+#head1 DESCRIPTION
+
+internal common test library
+
+#head1 AUTHOR
+
+I. Vlasenko, E<lt>viy@altlinux.orgE<gt>
+
+#head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2009 by I. Yu. Vlasenko.
+
+This library is free software; you can redistribute it and/or modify it under 
+either the LGPL2+ or under the same terms as Perl itself, either Perl version 5.8.4 
+or, at your option, any later version of Perl 5 you may have available.
+
+#cut
@@ -8,6 +8,7 @@
 use Test;
 BEGIN { plan tests => 1+4*8+2*7 };
 use HTML::Template::Pro;
+use lib "t";
 use HTML::Template::Pro::CommonTest;
 ok(1); # If we made it this far, we're ok.
 
@@ -23,7 +24,7 @@ HTML::Template::Pro->register_function( f1 => sub { return "F1: @_"; });
 HTML::Template::Pro->register_function( f2 => sub { return "F2: @_"; });
 HTML::Template::Pro->register_function( fUNDEF => sub { return undef; });
 
-my @exprset1=(ONE=>1,TWO=>2,THREE=>3,ZERO=>0,MINUSTEN=>-10, FILE=>'test_if1.tmpl', TWENTY=>20,FOURTY=>50);
+my @exprset1=(ONE=>1,TWO=>2,THREE=>3,ZERO=>0,MINUSTEN=>-10, FILE=>'test_if1.tmpl', TWENTY=>20,FOURTY=>50, EMPTYSTR=>'');
 my @brunoext=('FOO.BAR'=>'<test passed>');
 my @refset1=(
 HASHREF0=>[],
@@ -14,6 +14,7 @@ BEGIN {
 }
 use File::Spec;
 use HTML::Template::Pro;
+use lib "t";
 use HTML::Template::Pro::CommonTest;
 ok(1); # If we made it this far, we're ok.
 
@@ -0,0 +1,19 @@
+#!/usr/bin/perl -w
+use Test::More no_plan;
+use HTML::Template::Pro;
+
+my $src1 =<<"END;";
+</TMPL_IF>
+<tmpl_var EXPR="(a/(foo&&&">
+<TMPL_IF NAME="foo>
+<TMPL_FI NAME="foo>
+name foo
+END;
+
+my $template1   = HTML::Template::Pro->new(scalarref => \$src1, debug=> -1);
+$template1->param(foo => 1);
+my $out=$template1->output();
+#print $out;
+ok(1); # not crashed
+
+__END__
@@ -0,0 +1,14 @@
+#!/usr/bin/perl -w
+use Test::More no_plan;
+use HTML::Template::Pro;
+
+my $src1 =<<"END;";
+<tmpl_var EXPR="version()">
+END;
+
+my $template1   = HTML::Template::Pro->new(scalarref => \$src1, debug=> 0);
+my $out=$template1->output();
+print $out;
+ok(length($out)>0); 
+
+__END__
@@ -184,7 +184,6 @@ tag_handler_include (struct tmplpro_state *state, const PSTRING* const TagOptVal
 {
   struct tmplpro_param* param;
   char* filename;
-  const char* masterpath;
   int x;
   PSTRING varvalue;
   PSTRING defvalue;
@@ -209,16 +208,17 @@ tag_handler_include (struct tmplpro_state *state, const PSTRING* const TagOptVal
   };
   if (varvalue.begin==varvalue.endnext && defvalue.begin!=defvalue.endnext) varvalue=defvalue;
   /* pstrdup */
-  filename =(char*) malloc(varvalue.endnext-varvalue.begin+1);
-  for (x=0;x<varvalue.endnext-varvalue.begin;x++) {
-    *(filename+x)=*(varvalue.begin+x);
+  {
+    const long len = varvalue.endnext-varvalue.begin;
+    filename =(char*) malloc(len+1);
+    for (x=0;x<len;x++) {
+      *(filename+x)=*(varvalue.begin+x);
+    }
+    *(filename+len)=0;
   }
-  *(filename+(varvalue.endnext-varvalue.begin))=0;
   /* end pstrdup */
-  masterpath=param->masterpath; /* saving current file name */
   tmplpro_exec_tmpl_filename (param,filename);
   free (filename);
-  param->masterpath=masterpath;
   param->cur_includes--; 
   return;
 }
@@ -1,3 +1,5 @@
 <H1> test_esc4 </H1>
  \\<>\"; %FAhidden:\r\nend 
  
+VAR1
+Some&quot;&#39; Txt&#39;
@@ -2,3 +2,5 @@
 <tmpl_iF VAR4> <tmpl_var escape="JS" DEFAULT="test failed" NAME="STUFF1"> 
 <tmpl_else> <tmpl_var DEFault="test failed" name="STUFF1" ESCApe='js'> 
 </tmpl_if> 
+<tmpl_var name='VAR1' escape='html'>
+<tmpl_var name='STUFF2' escape='html'>
@@ -15,4 +15,11 @@ testing unescape string
 false:0
 true:1
 
+good
+good
+true:1
+true:1
+true:1
+false:0
+
 </body></html>
@@ -15,4 +15,11 @@ testing unescape string
 false:<TMPL_VAR EXPR="'\'1' eq '\'2'">
 true:<TMPL_VAR EXPR="'\'1' ne '\'2'">
 
+<tmpl_if expr="(EMPTYSTR eq SystemRequest_MainNavigationSelection)">bad<tmpl_else>good</tmpl_if>
+<tmpl_if expr="(EMPTYSTR eq '')">good<tmpl_else>bad</tmpl_if>
+true:<TMPL_VAR EXPR="'a' ge ''">
+true:<TMPL_VAR EXPR="'a' gt ''">
+true:<TMPL_VAR EXPR="'a' le ''">
+false:<TMPL_VAR EXPR="'a' lt ''">
+
 </body></html>
@@ -9,7 +9,11 @@
 #endif
 
 #ifndef PACKAGE_VERSION
+ #ifdef VERSION
+#define PACKAGE_VERSION VERSION
+ #else
 #define PACKAGE_VERSION "0.0(not defined)"
+ #endif
 #endif
 
 /*************************************************